#pragma once

#include "NodeStack.h"

template<class Node, class Factory>
Node * postfixParse(const std::string & input, const Factory & factory)
{
    NodeStack<Node> stack(input.size());
    
    for(std::string::const_iterator it = input.begin(); it != input.end(); ++it)
    {
        switch(*it)
        {
        case '|':
            stack.push(factory.createNodeOr(stack.pop(), stack.pop()));
            break;
        case '&':
            stack.push(factory.createNodeAnd(stack.pop(), stack.pop()));
            break;
        case '~': 
            stack.push(factory.createNodeNot(stack.pop())); 
            break;
        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
        case 'G':
        case 'H':
            stack.push(factory.createNodeAtom(std::string(1, *it))); 
            break;
        default:
            throw std::runtime_error("Unexpected symbol found in input string");
        }
    }
    
    Node * pResult = stack.pop();
    if(!stack.empty())
        throw std::runtime_error("Stack is not empty after parsing");
        
    return pResult;
}

